package com.iflytek.iot.redis.sharding.tools.utils;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @author zurun
 * @date 2020/3/2 14:35:57
 */
public class RedisClientInstanceUtils {

    public static RedisTemplate createRedisTemplate(boolean isJedis, RedisStandaloneConfiguration configuration, GenericObjectPoolConfig poolConfig) {
        RedisConnectionFactory factory;
        if (poolConfig == null) {
            if (isJedis) {
                JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(configuration);
                jedisConnectionFactory.afterPropertiesSet();
                factory = jedisConnectionFactory;
            } else {
                LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(configuration);
                lettuceConnectionFactory.afterPropertiesSet();
                factory = lettuceConnectionFactory;
            }
        } else {
            LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder().poolConfig(poolConfig).build();
            if (isJedis) {
                // 暂时不支持连接池
                JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(configuration);
                jedisConnectionFactory.afterPropertiesSet();
                factory = jedisConnectionFactory;
            } else {
                LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(configuration, clientConfiguration);
                lettuceConnectionFactory.afterPropertiesSet();
                factory = lettuceConnectionFactory;
            }
        }
        return getRedisTemplate(factory);
    }

    public static RedisTemplate createRedisTemplate(boolean isJedis, RedisSentinelConfiguration configuration, GenericObjectPoolConfig poolConfig) {
        RedisConnectionFactory factory;
        if (poolConfig == null) {
            if (isJedis) {
                JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(configuration);
                jedisConnectionFactory.afterPropertiesSet();
                factory = jedisConnectionFactory;
            } else {
                LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(configuration);
                lettuceConnectionFactory.afterPropertiesSet();
                factory = lettuceConnectionFactory;
            }
        } else {
            if (isJedis) {
                JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
                jedisPoolConfig.setMaxIdle(poolConfig.getMaxIdle());
                jedisPoolConfig.setMinIdle(poolConfig.getMinIdle());
                jedisPoolConfig.setMaxTotal(poolConfig.getMaxTotal());
                jedisPoolConfig.setMaxWaitMillis(poolConfig.getMaxWaitMillis());
                JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(configuration, jedisPoolConfig);
                jedisConnectionFactory.afterPropertiesSet();
                factory = jedisConnectionFactory;
            } else {
                LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder().poolConfig(poolConfig).build();
                LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(configuration, clientConfiguration);
                lettuceConnectionFactory.afterPropertiesSet();
                factory = lettuceConnectionFactory;
            }
        }
        return getRedisTemplate(factory);
    }

    public static RedisTemplate createRedisTemplate(boolean isJedis, RedisClusterConfiguration configuration, GenericObjectPoolConfig poolConfig) {
        RedisConnectionFactory factory;
        if (poolConfig == null) {
            if (isJedis) {
                JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(configuration);
                jedisConnectionFactory.afterPropertiesSet();
                factory = jedisConnectionFactory;
            } else {
                LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(configuration);
                lettuceConnectionFactory.afterPropertiesSet();
                factory = lettuceConnectionFactory;
            }
        } else {
            LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder().poolConfig(poolConfig).build();
            if (isJedis) {
                JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
                jedisPoolConfig.setMaxIdle(poolConfig.getMaxIdle());
                jedisPoolConfig.setMinIdle(poolConfig.getMinIdle());
                jedisPoolConfig.setMaxTotal(poolConfig.getMaxTotal());
                jedisPoolConfig.setMaxWaitMillis(poolConfig.getMaxWaitMillis());
                JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(configuration, jedisPoolConfig);
                jedisConnectionFactory.afterPropertiesSet();
                factory = jedisConnectionFactory;
            } else {
                LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(configuration, clientConfiguration);
                lettuceConnectionFactory.afterPropertiesSet();
                factory = lettuceConnectionFactory;
            }
        }
        return getRedisTemplate(factory);
    }


    private static RedisTemplate getRedisTemplate(RedisConnectionFactory factory) {

        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);


        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(stringRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(stringRedisSerializer);
        template.afterPropertiesSet();

        return template;
    }
}
